package com.padakeji.android.ui.widget;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by atanl on 2015/10/22.
 *
 * 官方RecyclerView的加强版
 * 加入添加header和footer的功能
 *
 */
public class RecyclerViewX extends RecyclerView {

    private static class FixedViewInfo {
        public View view;
        /**
         * The data backing the view.
         */
        public Object data;
        /**
         * <code>true</code> if the fixed view should be selectable
         */
        public boolean isSelectable;
    }

    public interface OnItemClickListener {
        void onItemClick(RecyclerViewX recyclerView, View view, int position, long id);
    }

    private RecyclerView.Adapter mAdapter;

    private ArrayList<FixedViewInfo> tempHeaderViewInfos = new ArrayList<>();
    private ArrayList<FixedViewInfo> tempFooterViewInfos = new ArrayList<>();

    private OnItemClickListener mOnItemClickListener;

    public RecyclerViewX(Context context) {
        super(context);
        init();
    }

    public RecyclerViewX(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RecyclerViewX(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {

    }

    public void setOnItemClickListener(OnItemClickListener l) {
        mOnItemClickListener = l;
        RecyclerView.Adapter adapter = super.getAdapter();
        if (adapter != null && adapter instanceof FixedAdapter) {
            ((FixedAdapter) adapter).setOnItemClickListener(l);
        }
    }

    public int getHeaderCount() {
        return tempHeaderViewInfos.size();
    }

    public int getFooterCount() {
        return tempFooterViewInfos.size();
    }

    public void addHeaderView(View view) {
        FixedViewInfo info = new FixedViewInfo();
        info.view = view;
        tempHeaderViewInfos.add(info);
        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    public void removeHeaderView(View v) {
        removeFixedViewFrom(tempHeaderViewInfos, v);
        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    public void clearHeaderViews() {
        tempHeaderViewInfos.clear();
        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }


    public void addFooterView(View view) {
        FixedViewInfo info = new FixedViewInfo();
        info.view = view;
        tempFooterViewInfos.add(info);
        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    public void removeFooterView(View v) {
        removeFixedViewFrom(tempFooterViewInfos, v);
        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    private void removeFixedViewFrom(List<FixedViewInfo> infos, View v) {
        int i, size = infos.size();
        for (i = 0; i < size; ++i) {
            FixedViewInfo info = infos.get(i);
            if (info.view == v) {
                infos.remove(i);
                break;
            }
        }
    }

    public void clearFooterViews() {
        tempFooterViewInfos.clear();
        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void setAdapter(RecyclerView.Adapter adapter) {
        mAdapter = adapter;
        if (adapter != null) {
            FixedAdapter fixedAdapter = new FixedAdapter(this, adapter, tempHeaderViewInfos, tempFooterViewInfos);
            fixedAdapter.setOnItemClickListener(mOnItemClickListener);
            super.setAdapter(fixedAdapter);
        } else {
            super.setAdapter(null);
        }
    }


    @Override
    public RecyclerView.Adapter getAdapter() {
        return mAdapter;
    }

    private static class FixedAdapter extends RecyclerView.Adapter {

        final int VIEW_TYPE_HEADER = -1832;
        final int VIEW_TYPE_FOOTER = -7382;

        RecyclerViewX mAttachedRecycler;
        RecyclerView.Adapter mAdapter;
        List<FixedViewInfo> mHeaderViewInfos;
        List<FixedViewInfo> mFooterViewInfos;
        OnItemClickListener mOnItemClickListener;

        FixedAdapter(@NonNull RecyclerViewX recyclerView, @NonNull RecyclerView.Adapter adapter, @NonNull List<FixedViewInfo> headerViewInfos, @NonNull List<FixedViewInfo> footerViewInfos) {
            mAttachedRecycler = recyclerView;
            mAdapter = adapter;
            mHeaderViewInfos = headerViewInfos;
            mFooterViewInfos = footerViewInfos;
        }

        public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
            this.mOnItemClickListener = onItemClickListener;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == VIEW_TYPE_HEADER || viewType == VIEW_TYPE_FOOTER) {
                return new FixedViewHolder(mAttachedRecycler.getContext());
            } else {
                return mAdapter.onCreateViewHolder(parent, viewType);
            }
        }

        @Override
        public int getItemViewType(int position) {
            if (position < getHeaderCount()) {
                return VIEW_TYPE_HEADER;
            } else if (position >= getHeaderCount() + mAdapter.getItemCount()) {
                return VIEW_TYPE_FOOTER;
            }
            return mAdapter.getItemViewType(position);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            int itemViewType = getItemViewType(position);
            switch (itemViewType) {
                case VIEW_TYPE_HEADER:
                    ViewGroup headerContainer = (ViewGroup)holder.itemView;
                    headerContainer.removeAllViews();
                    headerContainer.addView(mHeaderViewInfos.get(position).view);
                    break;
                case VIEW_TYPE_FOOTER:
                    ViewGroup footerContainer = (ViewGroup)holder.itemView;
                    footerContainer.removeAllViews();
                    try {
                        footerContainer.addView(mFooterViewInfos.get(mFooterViewInfos.size() - getItemCount() + position).view);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    final int originalPos = position - getHeaderCount();
                    holder.itemView.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (mOnItemClickListener != null) {
                                mOnItemClickListener.onItemClick(mAttachedRecycler, holder.itemView, originalPos, getItemId(originalPos));
                            }
                        }
                    });
                    mAdapter.onBindViewHolder(holder, originalPos);
                    break;
            }
        }

        int getHeaderCount() {
            return mHeaderViewInfos == null ? 0 : mHeaderViewInfos.size();
        }

        int getFooterCount() {
            return mFooterViewInfos == null ? 0 : mFooterViewInfos.size();
        }

        @Override
        public int getItemCount() {
            return mAdapter.getItemCount() + getHeaderCount() + getFooterCount();
        }

        @Override
        public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) {
            if (mAdapter != null) {
                mAdapter.registerAdapterDataObserver(observer);
            }
        }

        @Override
        public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
            if (mAdapter != null) {
                mAdapter.unregisterAdapterDataObserver(observer);
            }
        }
    }


    private static class FixedViewHolder extends RecyclerView.ViewHolder {
        FixedViewHolder(@NonNull Context context) {
            super(new FrameLayout(context));
            LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            super.itemView.setLayoutParams(params);
        }
    }

}
